/**
 * 图片OCR识别节点插件（PaddleOCR）
 * 1. 插件必须导出class，class名称与文件夹名一致（ImageOcrNodePlugin）
 * 2. 实现getConfigSchema、getHandler、getMeta方法
 * 3. handler通过child_process调用本地python脚本实现OCR
 * // python.exe -m pip install --target=../site-packages paddleocr paddlepaddle
 */
class ImageOcrNodePlugin {

    constructor(options = {}) {
        this.name = 'ImageOcrNodePlugin';
        
        // 从沙盒注入的能力中获取必需的功能
        this.httpClient = options.httpClient;
        this.httpRequest = options.httpRequest; // 添加 httpRequest 支持
        this.fs = options.fs;
        this.path = options.path;
        this.spawn = options.spawn;
        this.showDialog = options.showDialog;
        this.__dirname = options.__dirname;
        this.zipExtract = options.zipExtract;
        this.zipList = options.zipList;
        this.writeFileSync = options.writeFileSync;
        this.mkdirSync = options.mkdirSync;
        
        // 初始化状态
        this.initialized = false;
        this.initPromise = null;
        this.pythonEnvPath = null;
        this.envStatusFile = this.path.join(this.__dirname, '.env_status.json');
        this.isInitializing = false; // 添加初始化进行中标志
        
        // 在构造函数中尝试恢复环境状态
        this.loadEnvStatus();
        
        console.log('[ImageOcrNode] 沙盒模式初始化', {
            hasHttp: !!this.httpClient,
            hasFS: !!this.fs,
            hasProcess: !!this.spawn,
            hasZip: !!this.zipExtract,
            hasDialog: !!this.showDialog,
            initialized: this.initialized,
            pythonEnvPath: this.pythonEnvPath
        });
        
        // 验证必需能力
        this.validateRequiredCapabilities();
    }
    
    /**
     * 验证必需的沙盒能力
     */
    validateRequiredCapabilities() {
        const requiredCapabilities = [
            'httpClient', 'httpRequest', 'fs', 'path', 'spawn', 
            'zipExtract', 'writeFileSync', '__dirname'
        ];
        
        const missing = requiredCapabilities.filter(cap => !this[cap]);
        if (missing.length > 0) {
            throw new Error(`[ImageOcrNode] 缺少必需的沙盒能力: ${missing.join(', ')}`);
        }
        
        // 验证 httpClient 接口
        if (typeof this.httpClient.request !== 'function') {
            throw new Error('[ImageOcrNode] httpClient必须实现request方法');
        }
        
        // 验证 httpRequest 接口
        if (typeof this.httpRequest !== 'function') {
            throw new Error('[ImageOcrNode] httpRequest必须是一个函数');
        }
    }
    
    /**
     * 加载环境状态
     */
    loadEnvStatus() {
        try {
            if (this.fs.existsSync && this.fs.existsSync(this.envStatusFile)) {
                // 检查是否有 readFileSync 方法
                if (typeof this.fs.readFileSync === 'function') {
                    const statusContent = this.fs.readFileSync(this.envStatusFile, 'utf-8');
                    const status = JSON.parse(statusContent);
                    
                    if (status.initialized && status.pythonEnvPath) {
                        // 验证保存的环境路径是否仍然有效
                        if (this.fs.existsSync(status.pythonEnvPath)) {
                            this.pythonEnvPath = status.pythonEnvPath;
                            this.initialized = true;
                            console.log('[ImageOcrNode] 从状态文件恢复环境配置:', status.pythonEnvPath);
                        } else {
                            console.log('[ImageOcrNode] 状态文件中的环境路径已失效，将重新初始化');
                            this.clearEnvStatus();
                        }
                    }
                } else {
                    console.log('[ImageOcrNode] fs.readFileSync 不可用，跳过状态恢复');
                }
            }
        } catch (e) {
            console.warn('[ImageOcrNode] 加载环境状态失败:', e.message);
        }
    }
    
    /**
     * 保存环境状态
     */
    async saveEnvStatus() {
        try {
            const status = {
                initialized: this.initialized,
                pythonEnvPath: this.pythonEnvPath,
                timestamp: Date.now()
            };
            await this.writeFileSync(this.envStatusFile, JSON.stringify(status, null, 2), 'utf-8');
            console.log('[ImageOcrNode] 环境状态已保存');
        } catch (e) {
            console.warn('[ImageOcrNode] 保存环境状态失败:', e.message);
        }
    }
    
    /**
     * 清除环境状态
     */
    clearEnvStatus() {
        try {
            if (this.fs.existsSync && this.fs.existsSync(this.envStatusFile)) {
                if (typeof this.fs.unlinkSync === 'function') {
                    this.fs.unlinkSync(this.envStatusFile);
                } else {
                    console.log('[ImageOcrNode] fs.unlinkSync 不可用，无法删除状态文件');
                }
            }
            this.initialized = false;
            this.pythonEnvPath = null;
            console.log('[ImageOcrNode] 环境状态已清除');
        } catch (e) {
            console.warn('[ImageOcrNode] 清除环境状态失败:', e.message);
        }
    }
    
    /**
     * 动态设置 HTTP 客户端（向后兼容）
     */
    setHttpClient(httpClient) {
        if (httpClient && typeof httpClient.request === 'function') {
            this.httpClient = httpClient;
            console.log('[ImageOcrNode] HTTP 客户端已更新');
        } else {
            console.warn('[ImageOcrNode] 无效的 httpClient');
        }
    }

    /**
     * 使用 httpRequest 方式下载文件
     * @param {string} url 下载链接
     * @param {Object} options 请求选项
     * @returns {Promise<Buffer>} 下载的文件内容
     */
    async downloadFile(url, options = {}) {
        console.log(`[ImageOcrNode] 开始下载文件: ${url}`);
        
        try {
            // 优先使用 httpRequest（新沙盒系统注入的方法）
            if (this.httpRequest && typeof this.httpRequest === 'function') {
                console.log('[ImageOcrNode] 使用 httpRequest 下载');
                const result = await this.httpRequest(url, {
                    method: 'GET',
                    timeout: options.timeout || 60000,
                    ...options
                });
                
                if (result && result.body) {
                    console.log(`[ImageOcrNode] httpRequest 下载成功，大小: ${result.body.length} bytes`);
                    return result.body;
                } else if (result && result.data) {
                    // 兼容不同的返回格式
                    console.log(`[ImageOcrNode] httpRequest 下载成功，大小: ${result.data.length} bytes`);
                    return result.data;
                } else {
                    throw new Error('httpRequest 返回数据格式异常: ' + JSON.stringify(result));
                }
            }
            
            // 回退使用 httpClient.request（旧系统）
            if (this.httpClient && typeof this.httpClient.request === 'function') {
                console.log('[ImageOcrNode] 回退使用 httpClient.request 下载');
                const result = await this.httpClient.request(url, {
                    method: 'GET',
                    timeout: options.timeout || 60000,
                    ...options
                });
                
                if (result && result.body) {
                    console.log(`[ImageOcrNode] httpClient 下载成功，大小: ${result.body.length} bytes`);
                    return result.body;
                } else {
                    throw new Error('httpClient 返回数据格式异常: ' + JSON.stringify(result));
                }
            }
            
            throw new Error('没有可用的 HTTP 下载方法');
            
        } catch (error) {
            console.error(`[ImageOcrNode] 下载失败: ${url}`, error);
            throw new Error(`下载失败: ${error.message}`);
        }
    }
    /**
     * 快速检查Python环境是否可用（不执行完整初始化）
     */
    async quickCheckPythonEnv() {
        const pythonDir = this.path.join(this.__dirname, 'python');
        const pythonExe = this.path.join(pythonDir, 'python.exe');
        
        // 检查基本文件是否存在
        if (!this.fs.existsSync(pythonExe)) {
            return { available: false, reason: 'Python可执行文件不存在' };
        }
        
        const sitePackagesDir = this.path.join(pythonDir, 'Lib', 'site-packages');
        if (!this.fs.existsSync(sitePackagesDir)) {
            return { available: false, reason: 'site-packages目录不存在' };
        }
        
        return { available: true, pythonExe };
    }
    
    /**
     * 检查Python环境是否完整（包括依赖包）
     */
    async checkPythonEnvComplete() {
        const pythonDir = this.path.join(this.__dirname, 'python');
        const pythonExe = this.path.join(pythonDir, 'python.exe');
        const sitePackagesDir = this.path.join(pythonDir, 'Lib', 'site-packages');
        
        // 检查Python可执行文件
        if (!this.fs.existsSync(pythonExe)) {
            console.log('[ImageOcrNode] Python可执行文件不存在:', pythonExe);
            return false;
        }
        
        // 检查site-packages目录
        if (!this.fs.existsSync(sitePackagesDir)) {
            console.log('[ImageOcrNode] site-packages目录不存在:', sitePackagesDir);
            return false;
        }
        
        // 通过执行Python命令检查依赖包是否可用
        try {
            console.log('[ImageOcrNode] 检查paddleocr依赖包...');
            const checkResult = await this.spawn(pythonExe, ['-c', 'import paddleocr; print("paddleocr_ok")'], {
                stdio: ['ignore', 'pipe', 'pipe'],
                timeout: 15000
            });
            
            if (checkResult && checkResult.code === 0 && checkResult.stdout && checkResult.stdout.includes('paddleocr_ok')) {
                console.log('[ImageOcrNode] paddleocr依赖包检查通过');
                return true;
            } else {
                console.log('[ImageOcrNode] paddleocr依赖包检查失败:', {
                    code: checkResult?.code,
                    stdout: checkResult?.stdout,
                    stderr: checkResult?.stderr
                });
                return false;
            }
        } catch (e) {
            console.log('[ImageOcrNode] 依赖包检查异常:', e.message);
            return false;
        }
    }
    
    /**
     * 自动初始化绿色版 Python 环境（沙盒适配版本）
     */
    async initPythonEnv() {
        const pythonDir = this.path.join(this.__dirname, 'python');
        const pythonExe = this.path.join(pythonDir, 'python.exe');
        
        // 先检查环境是否已经完整
        const envComplete = await this.checkPythonEnvComplete();
        if (envComplete) {
            console.log('[ImageOcrNode] Python环境已存在且完整，跳过初始化');
            this.pythonEnvPath = pythonExe; // 设置环境路径
            
            // 如果当前未标记为已初始化，则保存状态
            if (!this.initialized) {
                this.initialized = true;
                await this.saveEnvStatus();
                console.log('[ImageOcrNode] 环境状态已更新保存');
            }
            
            return true;
        }
        
        // 如果环境不完整，则进行初始化
        console.log('[ImageOcrNode] Python环境不完整，开始初始化...');
        
        const pythonZipUrl = 'https://mindock.oss-cn-shenzhen.aliyuncs.com/python-3.10.11-embed-amd64.zip';
        const pythonZipPath = this.path.join(this.__dirname, 'python-3.10.11-embed-amd64.zip');
        
        const stepLog = (step, detail) => {
            console.log(`[ImageOcrNode][PythonEnv] ${step}`, detail || '');
        };
        
        try {
            stepLog('STEP1: 开始下载Python zip包', { url: pythonZipUrl, target: pythonZipPath });
            const downloadTimeout = 60 * 1000;
            
            // 使用新的下载方法（优先 httpRequest）
            const downloadPromise = this.downloadFile(pythonZipUrl, { 
                timeout: downloadTimeout
            });
            
            const fileBody = await Promise.race([
                downloadPromise,
                new Promise((_, reject) => setTimeout(() => reject(new Error('下载超时')), downloadTimeout))
            ]);
            
            if (!fileBody || !fileBody.length) {
                throw new Error('下载 python zip 失败: 文件内容为空');
            }
            
            stepLog('STEP1: 下载完成，写入zip文件', { size: fileBody.length });
            await this.writeFileSync(pythonZipPath, fileBody, 'binary');

            stepLog('STEP2: 开始解压zip', { zip: pythonZipPath, to: pythonDir });
            const unzipTimeout = 30 * 1000;
            const unzipPromise = this.zipExtract(pythonZipPath, pythonDir);
            
            const unzipRes = await Promise.race([
                unzipPromise,
                new Promise((_, reject) => setTimeout(() => reject(new Error('解压超时')), unzipTimeout))
            ]);
            
            if (!unzipRes || unzipRes.error) {
                throw new Error('解压 python zip 失败: ' + (unzipRes?.error || '未知错误'));
            }
            stepLog('STEP2: 解压完成');

            stepLog('STEP3: 构建Lib/site-packages目录');
            const libDir = this.path.join(pythonDir, 'Lib');
            const sitePackagesDir = this.path.join(libDir, 'site-packages');
            
            if (!this.fs.existsSync(libDir)) {
                const res = await this.mkdirSync(libDir, { recursive: true });
                if (res && res.error) throw new Error('创建Lib目录失败: ' + res.error);
            }
            if (!this.fs.existsSync(sitePackagesDir)) {
                const res = await this.mkdirSync(sitePackagesDir, { recursive: true });
                if (res && res.error) throw new Error('创建site-packages目录失败: ' + res.error);
            }
            stepLog('STEP3: 目录构建完成');

            stepLog('STEP4: 写入python310._pth文件');
            const pthContent = 'python310.zip\n.\nLib\\site-packages\nimport site\n';
            await this.writeFileSync(this.path.join(pythonDir, 'python310._pth'), pthContent, 'utf-8');
            stepLog('STEP4: _pth文件写入完成');

            stepLog('STEP5: 下载 get-pip.py');
            const getPipUrl = 'https://mindock.oss-cn-shenzhen.aliyuncs.com/get-pip.py';
            
            // 使用新的下载方法（优先 httpRequest）
            const getPipContent = await this.downloadFile(getPipUrl, { 
                timeout: 30000
            });
            
            if (!getPipContent || !getPipContent.length) {
                throw new Error('下载 get-pip.py 失败: 文件内容为空');
            }
            
            const getPipPath = this.path.join(this.__dirname, 'get-pip.py');
            await this.writeFileSync(getPipPath, getPipContent, 'utf-8');
            stepLog('STEP5: get-pip.py 下载并写入完成', { getPipPath });

            stepLog('STEP6: 检查并安装pip');
            if (this.fs.existsSync(getPipPath)) {
                stepLog('STEP6: 安装pip', { getPipPath });
                await this.spawn(pythonExe, [getPipPath], { stdio: ['ignore', 'pipe', 'pipe'] });
                await this.spawn(pythonExe, ['-m', 'pip', 'install', '--upgrade', 'pip'], { stdio: ['ignore', 'pipe', 'pipe'] });
                stepLog('STEP6: pip安装完成');
            } else {
                stepLog('STEP6: 未检测到get-pip.py，跳过pip安装');
            }

            stepLog('STEP7: 安装依赖包 paddleocr/paddlepaddle/tk/urllib3');
            const pipTimeout = 120 * 1000;
            const pipInstall = async (args, desc) => {
                stepLog(`STEP7: pip安装 ${desc}`, { args });
                return await Promise.race([
                    this.spawn(pythonExe, args, { stdio: ['ignore', 'pipe', 'pipe'] }),
                    new Promise((_, reject) => setTimeout(() => reject(new Error(`${desc} 安装超时`)), pipTimeout))
                ]);
            };
            
            await pipInstall(['-m', 'pip', 'install', '-i', 'https://mirrors.ustc.edu.cn/pypi/web/simple', 'paddleocr', 'paddlepaddle'], 'paddleocr/paddlepaddle');
            await pipInstall(['-m', 'pip', 'install', 'tk'], 'tk');
            // 修正: 去掉对 urllib3<2 的引号，避免被当作字面量字符串安装失败
            await pipInstall(['-m', 'pip', 'install', 'urllib3<2'], 'urllib3<2');
            stepLog('STEP7: 依赖包安装完成');

            stepLog('STEP8: 环境验证 paddleocr');
            const checkTimeout = 30 * 1000;
            const checkRes = await Promise.race([
                this.spawn(pythonExe, ['-m', 'pip', 'show', 'paddleocr'], { stdio: ['ignore', 'pipe', 'pipe'] }),
                new Promise((_, reject) => setTimeout(() => reject(new Error('环境验证超时')), checkTimeout))
            ]);
            
            if (!checkRes || checkRes.code !== 0) {
                throw new Error('paddleocr 环境验证失败');
            }
            
            stepLog('STEP8: 环境验证通过');
            this.pythonEnvPath = pythonExe; // 保存Python环境路径
            
            // 保存环境状态到文件
            await this.saveEnvStatus();
            stepLog('STEP9: 环境状态已保存');
            
            return true;
            
        } catch (err) {
            stepLog('ERROR', err?.message);
            console.error('[ImageOcrNode] Python环境初始化失败:', err);
            
            if (this.showDialog) {
                await this.showDialog({
                    title: '依赖环境自动安装失败',
                    message: '自动安装 python 环境失败，请手动下载并解压 python 到插件目录。错误: ' + (err?.message || '未知错误'),
                    url: pythonZipUrl,
                    actions: [
                        { label: '复制下载地址', value: 'copy', type: 'primary' }
                    ]
                });
            }
            return false;
        }
    }
    
    /**
     * 确保Python环境已初始化
     */
    async ensurePythonEnv() {
        // 如果正在初始化中，等待完成
        if (this.isInitializing && this.initPromise) {
            console.log('[ImageOcrNode] 检测到正在初始化中，等待完成...');
            return await this.initPromise;
        }
        
        // 如果已经标记为初始化，先做快速检查确认环境仍然可用
        if (this.initialized && this.pythonEnvPath) {
            const quickCheck = await this.quickCheckPythonEnv();
            if (quickCheck.available && this.fs.existsSync(this.pythonEnvPath)) {
                console.log('[ImageOcrNode] 环境已初始化且可用，跳过重新初始化');
                return true;
            } else {
                console.log('[ImageOcrNode] 环境状态异常，重新初始化', quickCheck);
                this.initialized = false;
                this.pythonEnvPath = null;
                this.clearEnvStatus();
            }
        }
        
        // 如果环境路径为空，则重新加载状态
        if (!this.pythonEnvPath) {
            this.loadEnvStatus();
        }
        
        // 重置初始化状态，重新检查
        if (!this.initialized) {
            this.initPromise = null;
        }
        
        if (!this.initPromise) {
            this.isInitializing = true;
            this.initPromise = this.initPythonEnv().finally(() => {
                this.isInitializing = false;
            });
        }
        
        const result = await this.initPromise;
        this.initialized = result;
        return result;
    }

    getConfigSchema() {
        return [
            {
                type: 'input',
                field: 'imagePath',
                title: '图片路径',
                value: '',
                props: { placeholder: '请输入本地图片绝对路径' },
                validate: [{ required: true, message: '图片路径必填' }]
            },
            {
                type: 'select',
                field: 'lang',
                title: '语言',
                value: 'ch',
                options: [
                    { label: '中文', value: 'ch' },
                    { label: '英文', value: 'en' }
                ]
            }
        ];
    }

    getHandler() {
        const self = this;
        return {
            async run(nodeInstance, context, instanceId, processInstance) {
                console.log('[ImageOcrNode] 开始OCR处理', { nodeInstance: nodeInstance?.nodeId, instanceId });
                // 增加自动重试标记
                let retried = false;
                
                try {
                    // 首先确保Python环境已初始化
                    console.log('[ImageOcrNode] 开始检查Python环境状态', {
                        initialized: self.initialized,
                        pythonEnvPath: self.pythonEnvPath
                    });
                    
                    const envReady = await self.ensurePythonEnv();
                    if (!envReady) {
                        console.error('[ImageOcrNode] Python环境检查失败');
                        return { 
                            ocrText: '', 
                            text: '', 
                            error: 'ImageOcrNode: Python环境初始化失败，请检查网络连接或手动安装依赖',
                            success: false
                        };
                    }
                    
                    console.log('[ImageOcrNode] Python环境检查通过', {
                        pythonEnvPath: self.pythonEnvPath
                    });
                    
                    // 验证必需的能力
                    if (!self.fs || typeof self.fs.existsSync !== 'function') {
                        console.error('[ImageOcrNode] fs 能力无效', self.fs);
                        return { ocrText: '', text: '', error: 'ImageOcrNode: 文件系统能力不可用', success: false };
                    }
                    
                    if (!self.path || typeof self.path.join !== 'function') {
                        console.error('[ImageOcrNode] path 能力无效', self.path);
                        return { ocrText: '', text: '', error: 'ImageOcrNode: 路径处理能力不可用', success: false };
                    }
                    
                    if (!self.spawn) {
                        console.error('[ImageOcrNode] spawn 能力无效', self.spawn);
                        return { ocrText: '', text: '', error: 'ImageOcrNode: 进程执行能力不可用', success: false };
                    }

                    // 获取节点配置
                    let nodeDef;
                    if (processInstance && processInstance.definition && Array.isArray(processInstance.definition.nodes)) {
                        nodeDef = processInstance.definition.nodes.find(n => n.id === nodeInstance.nodeId);
                    }
                    
                    if (!nodeDef) {
                        console.error('[ImageOcrNode] 未找到节点定义', { nodeId: nodeInstance.nodeId });
                        throw new Error('ImageOcrNode: 未找到节点定义');
                    }

                    const config = nodeDef.config || {};
                    const imagePath = typeof config.imagePath === 'string'
                        ? config.imagePath.replace(/^[\u200e\u202a-\u202e]+/, '').trim()
                        : '';
                    const lang = config.lang || 'ch';
                    
                    console.log('[ImageOcrNode] 处理配置', { imagePath, lang });

                    // 验证输入参数
                    if (!imagePath) {
                        return { 
                            ocrText: '', 
                            text: '', 
                            error: 'ImageOcrNode: 图片路径不能为空，请检查节点配置',
                            success: false
                        };
                    }
                    
                    if (!self.fs.existsSync(imagePath)) {
                        return { 
                            ocrText: '', 
                            text: '', 
                            error: `ImageOcrNode: 图片文件不存在: ${imagePath}`,
                            success: false,
                            imagePath
                        };
                    }

                    // 验证OCR脚本存在
                    const scriptPath = self.path.join(self.__dirname, 'ocr_infer.py');
                    if (!self.fs.existsSync(scriptPath)) {
                        console.error('[ImageOcrNode] OCR脚本不存在', scriptPath);
                        return { 
                            ocrText: '', 
                            text: '', 
                            error: 'ImageOcrNode: OCR脚本文件缺失，请重新安装插件',
                            success: false,
                            imagePath 
                        };
                    }

                    // 验证Python可执行文件
                    const pythonExe = self.pythonEnvPath || self.path.join(self.__dirname, 'python', 'python.exe');
                    if (!self.fs.existsSync(pythonExe)) {
                        return { 
                            ocrText: '', 
                            text: '', 
                            error: 'ImageOcrNode: Python执行环境缺失，请重新初始化环境',
                            success: false,
                            imagePath 
                        };
                    }

                    // 执行OCR识别
                    console.log('[ImageOcrNode] 开始执行OCR', { pythonExe, scriptPath, imagePath, lang });
                    
                    let spawnResult;
                    try {
                        console.log('[ImageOcrNode] 开始执行OCR，预期时间：30-120秒（首次使用需下载模型）');
                        
                        spawnResult = await self.spawn(pythonExe, [scriptPath, imagePath, lang], { 
                            stdio: ['ignore', 'pipe', 'pipe'],
                            timeout: 180000, // 增加到3分钟超时，首次运行可能需要下载模型
                            encoding: 'utf8' // 明确指定UTF-8编码
                        });
                        console.log('[ImageOcrNode] OCR执行完成', {
                            code: spawnResult?.code,
                            hasStdout: !!spawnResult?.stdout,
                            hasStderr: !!spawnResult?.stderr,
                            stdoutLength: spawnResult?.stdout?.length || 0,
                            stderrLength: spawnResult?.stderr?.length || 0
                        });

                        // 新增: 处理脚本自修复退出码(98: 自动安装paddleocr, 99: urllib3降级)，自动重试一次
                        try {
                            const firstCode = spawnResult?.code;
                            const firstStdout = spawnResult?.stdout || '';
                            if (!retried && (firstCode === 98 || firstCode === 99 || firstStdout.includes('已自动降级urllib3') || firstStdout.includes('请重新运行本脚本'))) {
                                console.log('[ImageOcrNode] 检测到环境自修复执行 (exitCode=' + firstCode + '), 准备自动重试一次...');
                                retried = true;
                                // 轻微延迟，确保文件写入/安装完成
                                await new Promise(r => setTimeout(r, 500));
                                spawnResult = await self.spawn(pythonExe, [scriptPath, imagePath, lang], {
                                    stdio: ['ignore', 'pipe', 'pipe'],
                                    timeout: 180000,
                                    encoding: 'utf8'
                                });
                                console.log('[ImageOcrNode] 自修复后再次执行完成', {
                                    code: spawnResult?.code,
                                    stdoutLength: spawnResult?.stdout?.length || 0,
                                    stderrLength: spawnResult?.stderr?.length || 0
                                });
                            }
                        } catch (autoRetryErr) {
                            console.warn('[ImageOcrNode] 自修复自动重试过程异常', autoRetryErr?.message);
                        }
                    } catch (err) {
                        console.error('[ImageOcrNode] OCR执行失败', err);
                        
                        // 检查是否是超时错误
                        const isTimeout = err?.message?.includes('timeout') || err?.code === 'ETIMEDOUT';
                        const timeoutMsg = isTimeout ? 
                            'OCR处理超时（3分钟）。首次使用需要下载模型，请确保网络连接正常。如果是大图片，建议先压缩。' :
                            `OCR执行异常: ${err?.message || '未知错误'}`;
                            
                        return { 
                            ocrText: '', 
                            text: '', 
                            error: `ImageOcrNode: ${timeoutMsg}`,
                            success: false,
                            imagePath 
                        };
                    }

                    // 处理执行结果
                    const stdout = spawnResult?.stdout?.trim() || '';
                    const stderr = spawnResult?.stderr?.trim() || '';
                    const code = spawnResult?.code ?? -1;
                    
                    // 过滤stderr中的常见警告信息、模型下载信息和ANSI控制符
                    const filteredStderr = stderr
                        .split('\n')
                        .filter(line => {
                            const lowerLine = line.toLowerCase();
                            // 过滤掉各种非错误信息
                            return !lowerLine.includes('warning') &&
                                   !lowerLine.includes('deprecated') &&
                                   !lowerLine.includes('futurewarning') &&
                                   !lowerLine.includes('userwarning') &&
                                   !lowerLine.includes('use_textline_orientation') &&
                                   !lowerLine.includes('instead.') &&
                                   !lowerLine.includes('creating model') &&
                                   !lowerLine.includes('model files already exist') &&
                                   !lowerLine.includes('using cached files') &&
                                   !lowerLine.includes('to redownload') &&
                                   !lowerLine.includes('.paddlex') &&
                                   !lowerLine.includes('official_models') &&
                                   !line.includes('\u001b[') && // ANSI颜色代码
                                   !line.includes('信息:') &&   // 中文信息提示
                                   !line.includes('��Ϣ:') &&   // 乱码的中文信息
                                   line.trim().length > 0;
                        })
                        .join('\n')
                        .trim();
                    
                    console.log('[ImageOcrNode] Python执行结果详情', { 
                        code, 
                        stdoutPreview: stdout.substring(0, 300),
                        stderrPreview: stderr.substring(0, 300),
                        filteredStderrLength: filteredStderr.length,
                        fullStdoutLength: stdout.length,
                        fullStderrLength: stderr.length
                    });

                    // 改进结果解析逻辑
                    let ocrText = '';
                    let parseError = '';
                    
                    // 首先尝试从 stdout 解析 JSON 结果
                    if (stdout) {
                        try {
                            // 处理多行 JSON 输出，找到最后一个有效的 JSON
                            const lines = stdout.split('\n').filter(line => line.trim());
                            let finalResult = null;
                            let hasError = false;
                            
                            // 从后往前查找，首先找包含完整结果的JSON
                            for (let i = lines.length - 1; i >= 0; i--) {
                                const line = lines[i].trim();
                                if (line.startsWith('{')) {
                                    try {
                                        const parsed = JSON.parse(line);
                                        
                                        // 优先查找最终结果
                                        if (parsed.text !== undefined && parsed.success !== undefined) {
                                            finalResult = parsed;
                                            console.log('[ImageOcrNode] 找到最终结果', { line: i, text: parsed.text.substring(0, 100) });
                                            break;
                                        }
                                        
                                        // 检查是否有错误信息
                                        if (parsed.error) {
                                            parseError = parsed.error;
                                            hasError = true;
                                            console.log('[ImageOcrNode] 发现错误信息', parsed.error);
                                        }
                                    } catch (e) {
                                        // 继续尝试其他行
                                        console.log(`[ImageOcrNode] 第${i}行JSON解析失败:`, e.message);
                                    }
                                }
                            }
                            
                            if (finalResult) {
                                ocrText = finalResult.text || '';
                                if (finalResult.error) {
                                    parseError = finalResult.error;
                                }
                            } else if (!hasError) {
                                // 如果没有找到最终结果但也没有错误，可能是进程被中断
                                // 检查是否有进度信息表明OCR正在进行
                                const progressInfo = lines.filter(line => {
                                    try {
                                        const parsed = JSON.parse(line);
                                        return parsed.info && (
                                            parsed.info.includes('识别') || 
                                            parsed.info.includes('初始化成功') ||
                                            parsed.info.includes('ocr 方法')
                                        );
                                    } catch (e) {
                                        return false;
                                    }
                                });
                                
                                if (progressInfo.length > 0) {
                                    parseError = 'OCR进程未完成：识别过程中被中断或超时';
                                    console.log('[ImageOcrNode] 检测到OCR进程中断', { progressLines: progressInfo.length });
                                } else {
                                    // 尝试解析整个 stdout 作为单个JSON
                                    try {
                                        const parsed = JSON.parse(stdout);
                                        ocrText = parsed.text || parsed.ocrText || '';
                                        if (parsed.error) {
                                            parseError = parsed.error;
                                        }
                                    } catch (e2) {
                                        console.warn('[ImageOcrNode] 完整JSON解析也失败，尝试提取文本');
                                        parseError = `JSON解析失败: ${e2.message}`;
                                    }
                                }
                            }
                        } catch (e) {
                            console.warn('[ImageOcrNode] JSON 解析失败，使用原始输出', e.message);
                            parseError = `输出解析异常: ${e.message}`;
                        }
                    }
                    
                    // 检查是否有真正的错误（而不仅仅是警告或模型下载信息）
                    // 如果有stdout输出且可以解析到text，则认为成功
                    const hasValidOutput = ocrText && ocrText.length > 0 && !parseError;
                    
                    // 只有在真正没有有效输出时才检查错误
                    const hasRealError = !hasValidOutput && (
                        code >= 10 || // 我们的脚本用10+的退出码表示真正的错误
                        parseError ||
                        (code !== 0 && filteredStderr.length > 0 && 
                         (filteredStderr.includes('error') || 
                          filteredStderr.includes('异常') || 
                          filteredStderr.includes('failed') || 
                          filteredStderr.includes('无法') ||
                          filteredStderr.includes('not found') ||
                          filteredStderr.includes('找不到')))
                    );
                    
                    if (hasRealError) {
                        let errorMsg = parseError || `Python 脚本异常退出 (code: ${code})`;
                        
                        // 只有在有实际错误信息时才添加stderr详情
                        if (filteredStderr.length > 0) {
                            errorMsg += `\n详情: ${filteredStderr}`;
                        }
                        
                        // 特殊处理常见的PaddleOCR初始化错误
                        if (errorMsg.includes('Unknown argument') || errorMsg.includes('参数错误')) {
                            errorMsg += '\n\n这可能是PaddleOCR版本兼容性问题，建议更新到最新版本的PaddleOCR。';
                        }
                        
                        console.error('[ImageOcrNode] OCR 处理失败', { code, parseError, filteredStderr });
                        return { 
                            ocrText: '', 
                            text: '', 
                            error: `ImageOcrNode: ${errorMsg}`,
                            success: false,
                            imagePath,
                            debug: { code, stdout: stdout.substring(0, 500), stderr: stderr.substring(0, 500) }
                        };
                    }
                    
                    console.log('[ImageOcrNode] OCR识别完成', { 
                        textLength: ocrText?.length || 0,
                        preview: ocrText || ''
                    });

                    return { 
                        ocrText, 
                        text: ocrText, 
                        error: '', 
                        success: true,
                        imagePath 
                    };
                    
                } catch (error) {
                    console.error('[ImageOcrNode] 处理异常', error);
                    return { 
                        ocrText: '', 
                        text: '', 
                        error: `ImageOcrNode: 处理异常: ${error?.message || '未知错误'}`,
                        success: false
                    };
                }
            }
        };
    }

    getMeta() {
        return {
            type: 'image-ocr-node',
            name: '图片OCR识别',
            icon: 'el-icon-picture',
            desc: '基于PaddleOCR的图片文字识别节点',
            portDefs: [
                { key: 'in', type: 'input', side: 'left', offset: { x: 0, y: 32 } },
                { key: 'out', type: 'output', side: 'right', offset: { x: 0, y: 32 } }
            ],
            plusDefs: [
                {
                    key: 'plus-right', side: 'right', show: true, menuList: [
                        { type: 'image-ocr-node', label: '图片OCR识别' },
                        { type: 'end', label: '结束' }
                    ]
                }
            ]
        };
    }
}

module.exports = ImageOcrNodePlugin;
